package javaNIO1.pipe;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.Pipe;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Random;

/**
 * Created with Intel IDEA.
 * 管道使用
 *
 * @Auther: gjt
 * @Date: 2024/7/21 15:13
 */
public class PipeTest {

    private static ReadableByteChannel startWorker(int resp) throws IOException {
        // 开启一个管道  使用静态工厂类
        Pipe pipe = Pipe.open();
        StartWorker startWorker = new StartWorker(pipe.sink(), resp);
        startWorker.start();
        return pipe.source();
    }

    private static class StartWorker extends Thread {
        WritableByteChannel channel;
        private int resp;

        public StartWorker(WritableByteChannel channel, int resp) {
            this.channel = channel;
            this.resp = resp;
        }

        public void run() {
            ByteBuffer buffer = ByteBuffer.allocateDirect(100);
            try {
                for (int i = 0; i < this.resp; i++) {
                    doSomeWork(buffer);
                    //channel may not take it all at once  通道可能一次接收不完
                    while (channel.write(buffer) > 0) {

                    }
                }

                this.channel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    private static String[] products = {"No good deed goes unpunished", " To be, or what?", "No matter where you go, where you are", "Just say \"YO\"", "My karma ran over my dogma"};

    private static Random rand = new Random();
    private static void doSomeWork(ByteBuffer buffer) {
        int product = rand.nextInt(products.length);
        buffer.clear();
        buffer.put(products[product].getBytes());
        buffer.put("\r\n".getBytes());
        buffer.flip();
    }
    public static void main(String[] args) throws IOException {

        WritableByteChannel writableByteChannel = Channels.newChannel(System.out);
        ReadableByteChannel readableByteChannel = startWorker(10);

        ByteBuffer buffer = ByteBuffer.allocateDirect(100);
        while(readableByteChannel.read(buffer) > 0){
            buffer.flip();
            writableByteChannel.write(buffer);
            buffer.clear();
        }
    }

    /**
     * 通道工具类的方法
     *
     *   方 法                                                           返回                               描述
     * Channels.newChannel(InputStream in)                         ReadableByteChannel                  返回一个将从给定的输入流中读取数据的通道。
     * Channels.newChannel(OutputStream out)                       WritableByteChannel                  返回一个将从给定的输出流中输出写入数据的通道。
     * Channels.newInputStream(ReadableByteChannel rbc)            InputStream                          返回一个将从给定的通道读取字节的流。
     * Channels.newOutputStream(WritableByteChannel wbc)           OutputStream                         返回一个将从给定的通道写入字节的流。
     * Channels.newReader(ReadableByteChannel rbc,                  Reader                              返回一个Reader,他将从给定的通道中读取字节并依据提供的CharsetDecoder对读取的字节进行解码。
     *             CharsetDecoder dec, int minBufferCap)
     * Channels.newReader(ReadableByteChannel rbc,Sting csName)     Reader                              返回一个Reader,他将从给定的通道读取字节，并依据提供的字符集名称将读取的字节解码成字符。
     * Channels.newWriter(WritableByteChannel wbc,                  Writer                              返回一个Writer,他将使用提供的CharsetEncoder对象对字符编码并写入给定的通道。
     *             CharsetEncoder enc, int minBufferCap)
     * Channels.newWriter(WritableByteChannel wbc, String scName)   Writer                              返回一个Writer,他将依据提供的字符集名称对字符编码并写入给定通道。
     */


    public void test() throws FileNotFoundException {

        ReadableByteChannel readableByteChannel = Channels.newChannel(new FileInputStream("ssss"));
        WritableByteChannel writableByteChannel = Channels.newChannel(new FileOutputStream("SSS"));
        InputStream inputStream = Channels.newInputStream(readableByteChannel);
        OutputStream outputStream = Channels.newOutputStream(writableByteChannel);


    }
}
